import numpy as np
import pandas as pd
def log(a):
    if a!=0:
        return np.log(a)
    else:
        return 0
def shangquan(lst):
    for i in range(len(lst)):
        lst[i]=[(lst[i][j]-min(lst[i]))/(max(lst[i])-min(lst[i])) for j in range(len(lst[i]))]
        lst=[[lst[i][j]/sum(lst[i]) for j in range(len(lst[i]))] for i in range(len(lst))]
        lst=[[lst[i][j]*log(lst[i][j]) for j in range(len(lst[i]))] for i in range(len(lst))]
        h=[1/np.log(len(lst[i]))*sum(lst[i]) for i in range(len(lst))]
        h=[(1+h[i])/(sum(h)+len(h)) for i in range(len(h))]
        if 0.999<sum(h)<1.001:
            return h
        else:
            print(sum(h))
            return 'False'
import pandas as pd
import numpy as np
from openpyxl import Workbook
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False
######################灰色预测################################
def pj(a,t):
    b=[]
    for i in range((len(a)-t)):
       b.append(sum([a[j]/t for j in range(i,i+t)])) 
    return b
def huise(a):
    a1=tsu(a)
    re=[0 for i in range(len(a))]
    for i in range(1,len(a)):
        re[i]=(a1[i-1]+a1[i])/2
    jg=[]
    for i in range(1,len(a)):
        jg.append([-a[i],-re[i],1])
    y=[]
    for i in range(1,len(a)):
        y.append(a[i]-a[i-1])
    jg=np.array(jg)
    print(np.shape(jg))
    print(np.shape(jg.T))
    y=np.array(y)
    tp=np.matmul(jg.T,jg)
    tp=np.matmul(np.linalg.inv(tp),jg.T)
    jg=np.matmul(tp,y.T)
    return jg
def ep(a):
    if abs(a)<-10:
        return 0
    elif abs(a)>10:
        return 22000
    else:
        return np.exp(a)
def tsu(a):
    s=[]
    for i in range(len(a)):
        ts=0
        for j in range(i+1):
            ts+=a[j]
        s.append(ts)
    return s
def jie(lst):
    print(lst)
    return [(-lst[0]-(lst[0]**2-4*lst[1])**0.5)/2,(-lst[0]+(lst[0]**2-4*lst[1])**0.5)/2]
def jhs(a):
    return jie(huise(a))
def ejs(a,ls,je):
    jg=0
    if je[0].imag==0:
        for i in range(len(a)):
            jg+=(a[i]-ls[0]*ep(je[0]*i)-ls[1]*ep(je[1]*i)-ls[2])**2
    else:
        for i in range(len(a)):
            jg+=(a[i]-ep(je[0].real*i)*(np.sin(je[0].imag*i)*ls[0]+np.cos(je[0].imag*i)*ls[1])-ls[2])**2
    return jg
def nihe(a,t,re,je,r):
    for i in range(t):
        for j in range(3):
            rp=re.copy()
            rp[j]+=0.0000001*r
            if j==0:
                re[j]-=(ejs(a,rp,je)-ejs(a,re,je))*300
            elif j==1:
                re[j]-=(ejs(a,rp,je)-ejs(a,re,je))*300
            elif j==2:
                re[j]-=(ejs(a,rp,je)-ejs(a,re,je))*300
            else:
                print('err')
        if i%100==0:
            print(ejs(a,re,je))
    return re
#############################线性拟合#############
def xxnh(x,y):
    le=len(x)
    a=(sum([x[i]**2 for i in range(le)])*sum([y[i] for i in range(le)])-sum([x[i] for i in range(le)])*sum([x[i]*y[i] for i in range(le)]))
    b=(le*sum([x[i]*y[i] for i in range(le)])-sum([x[i] for i in range(le)])*sum([y[i] for i in range(le)]))
    a/=(le*sum([x[i]**2 for i in range(le)])-sum([x[i] for i in range(le)])**2)
    b/=(le*sum([x[i]**2 for i in range(le)])-sum([x[i] for i in range(le)])**2)
    print(b,a)
    plt.scatter([x[i] for i in range(le)],[y[i] for i in range(le)])
    plt.plot([x[i] for i in range(le)],[a+b*x[i] for i in range(le)])
    return [b,a]
##############################傅里叶####################
def tsu(a):
    s=[]
    for i in range(len(a)):
        ts=0
        for j in range(i+1):
            ts+=a[j]
        s.append(ts)
    return s
def cs(a,b,lst,lsq):
    res=0
    for i in range(len(lst)):
        res+=(lsq[i]-lst[i]*a-b)**2
    return res
def fly(a):
    xishu=[[0,0] for i in range(380*2)]
    xishu[0][0]=sum(a)/len(a)
    for i in list(range(1,10)):
        for k in range(2):
            xishu[i][k]=0
            for j in range(len(a)):
                xishu[i][k]+=(np.cos(2*np.pi*j*i/(365*8+2))*(1-k)+np.sin(2*np.pi*j*i/(365*8+2))*k)*a[j]*2/len(a)
    xishu[0][0]=sum(a)/len(a)
    xishu[0][1]=0
    return xishu
def js(xishu,t):
    re=xishu[0][0]
    for i in list(range(1,10)):
        for j in range(2):
            re+=(np.cos(2*np.pi*t*i/(365*8+2))*(1-j)+np.sin(2*np.pi*t*i/(365*8+2))*j)*xishu[i][j]
    return re
def ep(a):
    if abs(a)<-10:
        return 0
    elif abs(a)>10:
        return 22000
    else:
        return np.exp(a)
def cc(a):
    xishu=fly(a)
    global dc
    dc=xishu
    re=[]
    for i in range(len(a)):
        re.append(a[i]-js(xishu,i))
    return re
#######################拟合结果检验###################
def jisr(a,b):
    mx=np.mean(a)
    my=np.mean(b)
    x=0
    y=0
    z=0
    for i in range(len(a)):
        x+=(a[i]-mx)*(b[i]-my)
        y+=(a[i]-mx)**2
        z+=(b[i]-my)**2
    print(x/(y**0.5*z**0.5))
    return x/(y**0.5*z**0.5)
def niheydu(a,b):
    sst=0
    sse=0
    ag=sum(a)/len(a)
    for i in range(len(a)):
        sst+=(a[i]-ag)**2
        sse+=(a[i]-b[i])**2
    print(f"sse:{sse}")
    print(f"sst:{sst}")
    print(1-sse/sst)
    return 1-sse/sst
#################################周期显示###########################
def zqxs(da,ls):
    ps=[((sum([np.sin(j*np.pi*2/i)*2*da[j] for j in range(len(da))])/len(da))**2+(sum([np.cos(j*np.pi*2/i)*2*da[j] for j in range(len(da))])/len(da))**2)**0.5 for i in ls]
    plt.plot(ls,ps)
##########################四阶龙格库塔###########################
def lgkt(hanshu,t,y,dt):
    k1=hanshu(t,y)
    k2=hanshu(t+dt/2,y+k1*dt/2)
    k3=hanshu(t+dt/2,y+k2*dt/2)
    k4=hanshu(t+dt,y+k3*dt)
    return dt*(k1+2*k2+2*k3+k4)/6
import numpy as np
import matplotlib.pyplot as plt
###################画图###################
#plt.figure(figsize=(10,10))
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False
#plt.title()
#plt.xlabel()
#plt.ylabel()
#plt.xticks(,,rotation=60)
#plt.savefig()
#plt.show()
##################latex######################
def prtexct(mtx):
    mx=[len(mtx[i]) for i in range(len(mtx))]
    mx=max(mx)
    print(r"\begin{table}[h]")
    print(r"\centering")
    print(r"\begin{tabular}{"+"|l"*mx+"}")
    print(r"\hline")
    for i in range(len(mtx)):
        for j in range(mx):
            try:
                print(mtx[i][j],end='')
                if j!=mx-1:
                    print(" & ",end='')
                else:
                    print(r"\\ \hline")
            except:
                for ii in range(mx-j-1):
                    print(" & ",end='')
                print(r"\\ \hline")
                break
    print(r"\end{tabular}")          
    print(r"\end{table}")      
    return
##############excel##########################
from openpyxl import Workbook
def ptexcel(ls,na):
    tqi=Workbook()
    tqdi=tqi.active
    tqdi.append([])
    for i in ls:
        tqdi.append(i)
    tqi.save(na+".xlsx")
    del tqi
    del tqdi
##########################遗传框架##################
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import copy
import ray
import random as ra
def limit(lst):
    pass
def cg(lst):
    pass
def jieg(lst):
    pass
@ray.remote
def gx(tlst,t,limit,cg,jieg):
    p=copy.deepcopy(tlst)
    i=ra.randint(0, len(tlst))
    p[i]=cg(p[i])
    if limit(p[i]):
        if jieg(p[i])<=jieg(tlst[i]):
            tlst[i]=p[i]
            return tlst
        else:
            r=ra.random()
            if r<np.exp((jieg(tlst[i])-jieg(p[i]))/t):
                tlst[i]=p[i]
                return tlst
            return tlst
    return tlst
def tcg(t):
    return 1
def died(zlst,t,limit,cg,jieg):
    milst=[np.Infinity,0]
    for i in range(t):
        zlst=ray.get([gx.remote(zlst[i],tcg(t),limit,cg,jieg) for i in range(len(zlst))])
        tl=[[jieg(zlst[i]),zlst[i]]for i in range(len(zlst))]
        tl.sort(key=lambda x:x[0])#reverse=
        print(zlst)
        if tl[0][0]<milst[0]:
            milst=tl[0]
        for j in range(len(zlst)):
            r=ra.random()
            if r<0.8:
                zlst[j]=tl[0][1]
            elif r<0.9:
                zlst[j]=tl[1][1]
            elif r<0.97:
                zlst[j]=tl[2][1]
            else:
                zlst[j]=tl[3][1]
    print(milst)
def jieshao(na='k'):
    if na=='k' or na=='jieshao':
        print("熵权法:shangquan;")
        print("二阶灰色:huise,解其白化系数:jie,(jhs为前两部整合)拟合系数nihe;")
        print("返回积分数列:tsu,n段时间平均pj;")
        print("傅里叶:cc表是残差,周期显示:zqxs;")
        print("线性拟合:xxnh,相关系数:jisr,拟合优度niheydu;")
        print("函数修饰器: 龙格库塔,将欧拉的导数作为第一个变量,lgkt;")
        print("遗传算法:died;")
        print("打印出latex类型:pretexct,打印excel类型:ptexcel")
        print("具体说明,输入jieshao(函数名)")
    elif na=='lgkt':
        print("第一个为函数,第二个为当前时间,第三个为所求值,第四个是变化时间,返回的是直接增加的量")
    elif na=='ptexcel':
        print("第一个为需要打印的列表,第二个为保存名字")
    elif na=='prtexct':
        print("直接输入需要的二维列表")
    elif na=='cc':
        print("直接输入等间隔的一列数据")
    elif na=='shangquan':
        print("输入数据列表")
    elif na=='jisr' or na=='niheydu':
        print("同时间的两列数据")
    elif na=='tsu':
        print("输入一列数据")
    elif na=='pj':
        print("第一个为一列数据,第二个为平均时间")
    elif na=='zqxs':
        print("第一个为数据,第二个为需要的频率点")
    elif na=='huise':
        print("输入原始数据列,输出白化微分方程参数")
    elif na=='jie':
        print("将白化微分系数转化为解的指数")
    elif na=='jhs':
        print("整合huise与jie,返回指数大小,接下来可以选择手动带入初值或者最小二乘拟合(nihe)")
    elif na=='nihe':
        print("第一个为数据,第二个是迭代次数,第三个初始值,第四个为解出的指数,第五个是最小精度")
    else:
        print("写错了或我还没写这个")


